//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Diagnostics;

namespace OpenLS.UI
{
    internal class TwoLinePanel : StackPanel
    {
        public TwoLinePanel()
        {
            MinWidth = 40;
            Orientation = System.Windows.Controls.Orientation.Horizontal;
        }


        /* public bool UsesTwoLines
         {
             get { return (bool) GetValue(UsesTwoLinesProperty); }
             set { SetValue(UsesTwoLinesProperty, value); }
         }

         // Using a DependencyProperty as the backing store for UsesTwoLines.  This enables animation, styling, binding, etc...
         public static readonly DependencyProperty UsesTwoLinesProperty =
             DependencyProperty.Register("UsesTwoLines", typeof (bool), typeof (TwoLinePanel),
                                         new FrameworkPropertyMetadata(false, 
                                             //FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange,
                                             FrameworkPropertyMetadataOptions.None,
           
         * 
         * onTwoLineChanged));
         */

        static void onTwoLineChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
        {
            Debug.WriteLine("changed");
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            //\\ Debug.WriteLine("ArrangeOverride " + GetType());
            TwoLineControl parent = WindowServices.GetAncestor<TwoLineControl>(this);
            bool usesTwoLines1 = parent.UsesTwoLines;
            if (!usesTwoLines1)
                return base.ArrangeOverride(finalSize);
            var children = new List<FrameworkElement>();
            foreach (FrameworkElement child in Children)
            {
                children.Add(child);
            }
            if (children.Count == 0)
                return new Size(0, 0);
            if (children.Count == 1)
                children[0].Arrange(new Rect(new Point(), finalSize));

            double totalWidth = Enumerable.Sum(children, c => c.DesiredSize.Width);
            bool overflows = totalWidth > MinWidth;
            var topSize = new Size();
            var bottomSize = new Size();
            int lower = 0;
            int upper = children.Count - 1;
            topSize = computeSize(topSize, children[lower].DesiredSize);
            bottomSize = computeSize(bottomSize, children[upper].DesiredSize);
            while (upper - lower > 1)
            {
                if (topSize.Width < bottomSize.Width | !overflows)
                {
                    lower++;
                    topSize = computeSize(topSize, children[lower].DesiredSize);
                }
                else
                {
                    {
                        upper--;
                        bottomSize = computeSize(bottomSize, children[upper].DesiredSize);
                    }
                }
            }
            double x = finalSize.Width - topSize.Width;
            double lineHeight = Math.Max(topSize.Height, bottomSize.Height);
            x = x/2;
            for (int i = 0; i <= lower; i++)
            {
                var child = children[i];
                child.Arrange(new Rect(new Point(x, (lineHeight - child.DesiredSize.Height)/2), child.DesiredSize));
                x += child.DesiredSize.Width;
            }
            x = finalSize.Width - bottomSize.Width;
            x = x/2;
            for (int i = upper; i <= children.Count - 1; i++)
            {
                var child = children[i];
                child.Arrange(new Rect(new Point(x, lineHeight + (lineHeight - child.DesiredSize.Height)/2),
                                       child.DesiredSize));
                x += child.DesiredSize.Width;
            }
            return finalSize;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            //\\ Debug.WriteLine("MeasureOverride " + GetType());
            TwoLineControl parent = WindowServices.GetAncestor<TwoLineControl>(this);
            bool usesTwoLines = parent.UsesTwoLines;
            if (!usesTwoLines)
                return base.MeasureOverride(constraint);
            var children = new List<FrameworkElement>();
            foreach (FrameworkElement child in Children)
            {
                children.Add(child);
            }
            if (children.Count == 0)
                return new Size(0, 0);

            foreach (FrameworkElement child in children)
            {
                child.Measure(constraint);
            }
            if (children.Count == 1)
                return children[0].DesiredSize;
            double totalWidth = Enumerable.Sum(children, c => c.DesiredSize.Width);
            bool overflows = totalWidth > MinWidth;
            var topSize = new Size();
            var bottomSize = new Size();
            int lower = 0;
            int upper = children.Count - 1;
            topSize = computeSize(topSize, children[lower].DesiredSize);
            bottomSize = computeSize(bottomSize, children[upper].DesiredSize);
            while (upper - lower > 1)
            {
                if (topSize.Width < bottomSize.Width | !overflows)
                {
                    lower++;
                    topSize = computeSize(topSize, children[lower].DesiredSize);
                }
                else
                {
                    {
                        upper--;
                        bottomSize = computeSize(bottomSize, children[upper].DesiredSize);
                    }
                }
            }
            double lineHeight = Math.Max(topSize.Height, bottomSize.Height);
            return new Size(Math.Max(topSize.Width, bottomSize.Width), lineHeight + lineHeight);
        }

        private static Size computeSize(Size size, Size desiredSize)
        {
            return new Size(size.Width + desiredSize.Width, Math.Max(size.Height, desiredSize.Height));
        }
    }
}
    ;